package com.hiray.wanandroid.net

import android.util.Log
import com.google.gson.annotations.SerializedName
import com.hiray.wanandroid.net.response.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.withContext
import retrofit2.http.GET
import retrofit2.http.Path
import java.net.SocketTimeoutException

open class ResponseWrapper<T>(
    @SerializedName("errorMsg") val errMsg: String,
    @SerializedName("errorCode") val errCode: Int,
    val data: T? = null
) {
    val isSuccess: Boolean get() = errCode == 0
}

class PagingBody<P>(val datas: List<P>)

class PagingResponse<R>(
    errMsg: String,
    errCode: Int,
) : ResponseWrapper<PagingBody<R>>(errMsg, errCode) {

    val items: List<R> get() = data?.datas ?: emptyList()
}

class ErrorResponse(errMsg: String, errCode: Int) :
    ResponseWrapper<String>(errMsg, errCode, null)

suspend inline fun <T> apiCall(
    crossinline call: suspend CoroutineScope.() -> ResponseWrapper<T>,
): ResponseWrapper<T> {
    return withContext(Dispatchers.IO) {
        val res: ResponseWrapper<T>
        try {
            res = call()
        } catch (e: Throwable) {
            cancel()
            if (e is SocketTimeoutException) {
                Log.i("ApiCaller", "apiCall: 网络超时")
            }
            return@withContext ResponseWrapper(e.message!!, -1)
        }
        onApiError(res.errCode)
        return@withContext res
    }
}

suspend inline fun <T> pagingCall(
    crossinline call: suspend CoroutineScope.() -> PagingResponse<T>,
): PagingResponse<T> {
    return withContext(Dispatchers.IO) {
        val res: PagingResponse<T>
        try {
            res = call()
        } catch (e: Throwable) {
            cancel()
            return@withContext PagingResponse(e.message!!, -1)
        }
        onApiError(res.errCode)
        return@withContext res
    }
}

fun onApiError(errCode: Int) {

}

interface ApiService {
    @GET("article/list/{page}/json")
    suspend fun fetchHomeFeed(@Path("page") page: Int): PagingResponse<HomeFeed>

    @GET("banner/json")
    suspend fun fetchHomeBanner(): ResponseWrapper<List<HomeBanner>>

    @GET("article/top/json")
    suspend fun fetchPinnedFeed(): ResponseWrapper<List<HomeFeed>>

    @GET("user_article/list/{page}/json")
    suspend fun fetchSquareFeed(@Path("page") page: Int): PagingResponse<HomeFeed>

    @GET("wxarticle/chapters/json  ")
    suspend fun fetchPublicList(): ResponseWrapper<List<Public>>

    @GET("wxarticle/list/{id}/{page}/json")
    suspend fun fetchPublicArticleList(
        @Path("id") id: String,
        @Path("page") page: Int
    ): PagingResponse<PublicArticle>

    @GET("wenda/list/{pageId}/json")
    suspend fun fetchQaList(@Path("pageId")page:Int):PagingResponse<QaFeed>
}